/*
 * Copyright 2010 - Jeremie Brebec
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.jb.notification.client.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.jb.notification.client.Notification;
import org.jb.notification.client.NotificationListener;
import org.jb.notification.client.NotificationPool;
import org.jb.notification.client.Notifications;
import org.jb.notification.client.rpc.NotificationServiceAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * 
 * @author jeremie
 *
 */
@Singleton
public class NotificationPoolImpl implements NotificationPool {

	/**
	 * 
	 * @param room
	 */
	public NotificationPoolImpl() {}
	
	@SuppressWarnings("unchecked")
	@Inject
	public void setNotificationListener( Set<NotificationListener> listeners ) {
		for( NotificationListener<?> listener : listeners ) {
			this.listeners.put( listener.getType(), listener );		
		}
	}
	
	/**
	 * 
	 * @param notification
	 */
	@SuppressWarnings("unchecked")
	public void handleNotifications( Collection<Notification> notifications ) {
		for( Notification notification : notifications ) {
			
			NotificationListener<Notification> listener = (NotificationListener)listeners.get( notification.getType() );
			if (listener != null) {
				if (!GWT.isScript())  {
					listener.onNotification(notification);
				} else {
					// On ignore les exceptions en prod...	
					try {
						listener.onNotification(notification);		
					}
					catch( Exception e) {
						
					}
				}
			}
		}
	}

	/**
	 * 
	 */
	public void run() {
		DeferredCommand.addCommand( new Command() {

			@Override
			public void execute() {
				notificationService.getNotification( checkpoint, new AsyncCallback<Notifications>() {
					
					@Override
					public void onSuccess(Notifications result) {
						checkpoint = result.getCheckpoint();
						handleNotifications( result.getNotifications() );
						
						run();
					}
					
					@Override
					public void onFailure(Throwable caught) {
						run();
					}
				} );
				
			}
			
		} );
	}
	
	private long checkpoint;
		
	private Map< String, NotificationListener<?> > listeners = new HashMap< String, NotificationListener<?> >();

	@Inject
	private NotificationServiceAsync notificationService;
}
